{
  LX Mesh module

  Based on modo's SDK lxmesh.h which is:

  Copyright (c) 2008-2012 Luxology LLC

  Permission is hereby granted, free of charge, to any person obtaining a
  copy of this software and associated documentation files (the "Software"),
  to deal in the Software without restriction, including without limitation
  the rights to use, copy, modify, merge, publish, distribute, sublicense,
  and/or sell copies of the Software, and to permit persons to whom the
  Software is furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.   Except as contained
  in this notice, the name(s) of the above copyright holders shall not be
  used in advertising or otherwise to promote the sale, use or other dealings
  in this Software without prior written authorization.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  DEALINGS IN THE SOFTWARE.
}

{
  Copyright (c) 2012 David Ballesteros and Jameel Halabi

  This unit is part of the BLAISEmodo wrapper,
  which is licensed under the BSD 2-Clause license (see licenses/license.txt).
}


unit Lx_Mesh;

{$mode objfpc}{$H+}

interface

uses
  Lx_Result, Lx_VMath;

type
  PLXtMarkMode = ^LXtMarkMode;
  LXtMarkMode  = UInt32      ;

  PPLXtPoint   = ^PLXtPoint  ;
  PLXtPoint    = ^LXtPoint   ;
  LXtPoint     = record   end;

  PPLXtPolygon = ^PLXtPolygon;
  PLXtPolygon  = ^LXtPolygon ;
  LXtPolygon   = record   end;

  PPLXtEdge    = ^PLXtEdge   ;
  PLXtEdge     = ^LXtEdge    ;
  LXtEdge      = record   end;

  PLXtMeshMap  = ^LXtMeshMap ;
  LXtMeshMap   = record   end;

const
  LXa_EDGE                    = 'edge'       ;
  LXa_MESH                    = 'mesh'       ;
  LXa_MESHMAP                 = 'meshmap'    ;
  LXa_MESHSERVICE             = 'meshservice';
  LXa_POINT                   = 'point'      ;
  LXa_POLYGON                 = 'polygon'    ;

  LXf_MESHEDIT_POSITION       = $001;
  LXf_MESHEDIT_POINTS         = $002;
  LXf_MESHEDIT_POLYGONS       = $004;

  LXf_MESHEDIT_GEOMETRY       = LXf_MESHEDIT_POINTS or LXf_MESHEDIT_POLYGONS;

  LXf_MESHEDIT_POL_TAGS       = $008;
  LXf_MESHEDIT_POL_TYPE       = $010;

  LXf_MESHEDIT_MAP_CONTINUITY = $020;
  LXf_MESHEDIT_MAP_UV         = $040;
  LXf_MESHEDIT_MAP_MORPH      = $080;
  LXf_MESHEDIT_MAP_OTHER      = $100;

  LXiMARK_ANY                 = LXtMarkMode(0);

  LXiPSUB_BOUND_SMOOTH        = 0;
  LXiPSUB_BOUND_CREASE        = 1;

  LXi_POLY_MAXVERT            = 65535;

  LXiFILT_MODIFY              = 1;
  LXiFILT_GENERATE            = 2;
  LXiFILT_SOURCE              = 3;

  LXsMARK_HIDE                = 'hide'  ;
  LXsMARK_HALO                = 'halo'  ;
  LXsMARK_LOCK                = 'lock'  ;
  LXsMARK_SELECT              = 'select';

  LXsMARK_USER_0              = 'user0' ;
  LXsMARK_USER_1              = 'user1' ;
  LXsMARK_USER_2              = 'user2' ;
  LXsMARK_USER_3              = 'user3' ;
  LXsMARK_USER_4              = 'user4' ;
  LXsMARK_USER_5              = 'user5' ;
  LXsMARK_USER_6              = 'user6' ;
  LXsMARK_USER_7              = 'user7' ;

  LXsPTYP_FACE                = 'face'   ;
  LXsPTYP_CURVE               = 'curve'  ;
  LXsPTYP_BEZIER              = 'bezier' ;
  LXsPTYP_SUBD                = 'subdiv' ;
  LXsPTYP_SPCH                = 'spatch' ;
  LXsPTYP_TEXT                = 'text'   ;
  LXsPTYP_PSUB                = 'psubdiv';

  LXsVMAP_ITEMPREFIX          = '__item_';

  LXu_EDGE                    = '{19A44432-E2CF-4BCF-9EA6-D696E7A0F16E}';
  LXu_MESH                    = '{1F1BB7BF-A862-4810-95FF-3346AF738209}';
  LXu_MESHLISTENER            = '{957900AC-BC06-45D9-B1B1-9CC5A2AEC026}';
  LXu_MESHFILTER              = '{F5896BA1-7EC5-4EE9-852F-BF977E451953}';
  LXu_MESHFILTERBBOX          = '{FBD83166-4B50-42A0-8C91-C36D3BB76904}';
  LXu_MESHMAP                 = '{2AEBA454-2AC4-4F1E-B892-7A16F7601030}';
  LXu_MESHSERVICE             = '{82B739EC-F92E-4CC9-A5FB-584A866D5897}';
  LXu_POINT                   = '{37B477FE-ED3C-4EDC-A4A8-9BB24F58A4E6}';
  LXu_POLYGON                 = '{5839056D-28BF-4D72-8A26-E4AA00DA788F}';

type
  ILxMeshService = interface
  [LXu_MESHSERVICE]
    function ScriptQuery     (  out VObj                       ) : LxResult;
    function ModeCompose     (const &Set         : PChar       ;
                              const Clear        : PChar       ;
                                    Mode         : PLXtMarkMode) : LxResult;
    function VMapLookupType  (const Name         : PChar       ;
                                    &Type        : PLXtID4     ) : LxResult;
    function VMapLookupName  (      &Type        : LXtID4      ;
                              const Name         : PPChar      ) : LxResult;
    function VMapDimension   (      &Type        : LXtID4      ;
                                    Dimension    : PUint32     ) : LxResult;
    function VMapIsEdgeMap   (      &Type        : LXtID4      ) : LxResult;
    function VMapIsContinuous(      &Type        : LXtID4      ) : LxResult;
    function VMapZeroDefault (      &Type        : LXtID4      ) : LxResult;
    function CreateMesh      (  out VObj                       ) : LxResult;
    function ConvertMesh     (      TriGroupItem ,
                                    MeshItem     : IUnknown    ) : LxResult;
  end;

  ILxMesh= interface
  [LXu_MESH]
    function PointCount         (      Count    : PUInt32    ) : LxResult;
    function PolygonCount       (      Count    : PUInt32    ) : LxResult;
    function EdgeCount          (      Count    : PUInt32    ) : LxResult;
    function MapCount           (      Count    : PUInt32    ) : LxResult;
    function BoundingBox        (      Pick     : LXtMarkMode;
                                       BBox     : PLXtBBox   ) : LxResult;
    function MaxPointPolygons   (      Pick     : LXtMarkMode;
                                       Count    : PUInt32    ) : LxResult;
    function MaxPolygonSize     (      Pick     : LXtMarkMode;
                                       Count    : PUInt32    ) : LxResult;
    function PolyTagSetDefault  (      &Type    : LXtID4     ;
                                 const Tag      : PChar      ) : LxResult;
    function PointAccessor      (  out VObj                  ) : LxResult;
    function PolygonAccessor    (  out VObj                  ) : LxResult;
    function EdgeAccessor       (  out VObj                  ) : LxResult;
    function MeshMapAccessor    (  out VObj                  ) : LxResult;
    function SetMeshEdits       (      Edits    : UInt32     ) : LxResult;
    function SUBDGetLevel       (      N        : Integer    ) : LxResult;
    function SUBDSetLevel       (      N        : Integer    ) : LxResult;
    function SUBDGetLinearUV    (      IsLinear : PUInt32    ) : LxResult;
    function SUBDSetLinearUV    (      IsLinear : UInt32     ) : LxResult;
    function PSUBGetBoundRule   (      Bound    : Integer    ) : LxResult;
    function PSUBSetBoundRule   (      Bound    : Integer    ) : LxResult;
    function TestSameMesh       (      Other    : IUnknown   ) : LxResult;
    function PTagCount          (      &Type    : LXtID4     ) : LxResult;
    function PTagByIndex        (      &Type    : LXtID4     ;
                                       Index    : UInt32     ;
                                       Tag      : PChar      ) : LxResult;
    function PSUBGetLevel       (      N        : PInteger   ) : LxResult;
    function PSUBSetLevel       (      N        : Integer    ) : LxResult;
    function PSUBGetCurrentLevel(      N        : PInteger   ) : LxResult;
    function PSUBSetCurrentLevel(      N        : Integer    ) : LxResult;
  end;

  ILxPoint = interface
  [LXu_POINT]
    function Spawn              (  out VObj                   ) : LxResult ;
    function Enumerate          (      Mode      : LXtMarkMode;
                                       Visitor   : IUnknown   ;
                                       Monitor   : IUnknown   ) : LxResult ;
    function TestMarks          (      Mode      : LXtMarkMode) : LxResult ;
    function SetMarks           (      &Set      : LXtMarkMode) : LxResult ;
    function Select             (      Point     : PLXtPoint  ) : LxResult ;
    function SelectByIndex      (      Index     : UInt32     ) : LxResult ;
    function SelectPolygonVertex(      Polygon   : PLXtPolygon;
                                       Index     : UInt32     ) : LxResult ;
    function ID                                                 : PLXtPoint;
    function Index              (      Index     : PUInt32    ) : LxResult ;
    function Pos                (      Pos       : LXtFVector ) : LxResult ;
    function Normal             (      Pol       : PLXtPolygon;
                                       Normal    : LXtVector  ) : LxResult ;
    function MapValue           (      Map       : PLXtMeshMap;
                                       Value     : PSingle    ) : LxResult ;
    function MapEvaluate        (      Map       : PLXtMeshMap;
                                       Value     : PSingle    ) : LxResult ;
    function PolygonCount       (      Count     : PUInt32    ) : LxResult ;
    function PolygonByIndex     (      Index_    : PUInt32    ;
                                       PolygonID : PPLXtPolygon) : LxResult ;
    function New                (      Pos_      : LXtVector  ;
                                       PointID   : PPLXtPoint ) : LxResult ;
    function Copy               (      PointID   : PPLXtPoint ) : LxResult ;
    function Remove                                             : LxResult ;
    function SetPos             (      Pos_      : LXtVector  ) : LxResult ;
    function SetMapValue        (      Map       : PLXtMeshMap;
                                 const Value     : PSingle    ) : LxResult ;
    function ClearMapValue      (      Map       : PLXtMeshMap) : LxResult ;
    function Corner             (      Pos_      : LXtFVector ) : LxResult ;
    function PointCount         (      Count     : PUInt32    ) : LxResult ;
    function PointByIndex       (      Index_    : UInt32     ;
                                       PointID   : PPLXtPoint ) : LxResult ;
    function EdgeCount          (      Count     : PUInt32    ) : LxResult ;
    function EdgeByIndex        (      Index_    : UInt32     ;
                                       EdgeID    : PPLXtEdge   ) : LxResult ;
  end;

  ILxPolygon = interface
  [LXu_POLYGON]
    function Spawn                    (  out VObj                   ) : LxResult   ;
    function Enumerate                (      Mode      : LXtMarkMode;
                                             Visitor   ,
                                             Monitor   : IUnknown   ) : LxResult   ;
    function TestMarks                (      Mode      : LXtMarkMode) : LxResult   ;
    function SetMarks                 (      &Set      : LXtMarkMode) : LxResult   ;
    function Select                   (      Polygon   : PLXtPolygon) : LxResult   ;
    function SelectByIndex            (      Index     : UInt32     ) : LxResult   ;
    function ID                                                       : PLXtPolygon;
    function Index                    (      Index     : PInteger   ) : LxResult   ;
    function &Type                    (      &Type     : PLXtID4    ) : LxResult   ;
    function VertexCount              (      Count     : PUInt32    ) : LxResult   ;
    function VertexByIndex            (      Index_    : UInt32     ;
                                             Point     : PPLXtPoint ) : LxResult   ;
    function FirstIsControlEndpoint                                   : LxResult   ;
    function LastIsControlEndpoint                                    : LxResult   ;
    function Normal                   (      Normal    : LXtVector  ) : LxResult   ;
    function MapValue                 (      Map       : PLXtMeshMap;
                                             Point     : PLXtPoint  ;
                                             Value     : PSingle    ) : LxResult   ;
    function MapEvaluate              (      Map       : PLXtMeshMap;
                                             Point     : PLXtPoint  ;
                                             Value     : PSingle    ) : LxResult   ;
    function New                      (      Type_     : LXtID4     ;
                                       const Vertices  : PPLXtPoint ;
                                             NumVert   : UInt32     ;
                                             Rev       : UInt32     ;
                                             PolygonID : PPLXtPolygon) : LxResult   ;
    function NewProto                 (      Type_     : LXtID4     ;
                                       const Vertices  : PPLXtPoint  ;
                                             NumVert   : UInt32     ;
                                             Rev       : UInt32     ;
                                             PolygonID : PPLXtPolygon) : LxResult   ;
    function Remove                                                   : LxResult   ;
    function SetFirstIsControlEndpoint(      State     : Integer    ) : LxResult   ;
    function SetLastIsControlEndpoint (      State     : Integer    ) : LxResult   ;
    function SetVertexList            (const Vertices  : PPLXtPoint  ;
                                             NumVert   : UInt32     ;
                                             Rev       : UInt32     ) : LxResult   ;
    function SetMapValue              (      Point     : PLXtPoint  ;
                                             Map       : PLXtMeshMap;
                                       const Value     : PSingle    ) : LxResult   ;
    function ClearMapValue            (      Point     : PLXtPoint  ;
                                             Map       : PLXtMeshMap) : LxResult   ;
    function StartContour                                             : LxResult   ;
    function AddContourEdge           (      StartPt   : PLXtPoint  ;
                                             EndPt     : PLXtPoint  ) : LxResult   ;
    function GenerateContour          (      Type_     : LXtID4     ;
                                             PolygonID : PLXtPolygon) : LxResult   ;
    function GenerateContourProto     (      PolygonID : PLXtPolygon) : LxResult   ;
    function IntersectRay             (const Pos       : LXtVector  ;
                                       const Dir       : LXtVector  ;
                                             HitNorm   : LXtVector  ;
                                             HitDist   : PDouble    ) : LxResult   ;
    function Closest                  (      MaxDist   : Double     ;
                                       const Pos       : LXtVector  ;
                                             HitPos    ,
                                             HitNorm   : LXtVector  ;
                                             HitDist   : PDouble    ) : LxResult   ;
    function PointIndex               (      PointID   : PLXtPoint  ;
                                             Index_    : PUInt32    ) : LxResult   ;
    function EdgeIndex                (      EdgeID    : PLXtEdge   ;
                                             Index_    : PUInt32    ) : LxResult   ;
    function SharedEdge               (      PolygonID : PLXtPolygon;
                                             EdgeID    : PPLXtEdge  ) : LxResult   ;
    function IsBorder                                                 : LxResult   ;
    function RepresentativePosition   (      Pos       : LXtVector  ) : LxResult   ;
    function GoodPoint                (const Points    : PPLXtPoint  ;
                                             NPoints   : UInt32     ;
                                             Index_    : PUInt32    ) : LxResult   ;
  end;

  ILxEdge = interface
  [LXu_EDGE]
    function Spawn                (  out VObj                   ) : LxResult;
    function Enumerate            (      Mode      : LXtMarkMode;
                                         Visitor   ,
                                         Monitor   : IUnknown   ) : LxResult;
    function TestMarks            (      Mode      : LXtMarkMode) : LxResult;
    function SetMarks             (      &Set      : LXtMarkMode) : LxResult;
    function Select               (      Edge      : PLXtEdge   ) : LxResult;
    function SelectEndpoints      (      V0        : PLXtPoint  ;
                                         V1        : PLXtPoint  ) : LxResult;
    function ID                                                   : PLXtEdge;
    function Endpoints            (      Point0    : PPLXtPoint  ;
                                         Point1    : PPLXtPoint  ) : LxResult;
    function MapValue             (      Map       : PLXtMeshMap;
                                         Value     : PSingle    ) : LxResult;
    function MapEvaluate          (      Map       : PLXtMeshMap;
                                         Value     : PSingle    ) : LxResult;
    function SetMapValue          (      Map       : PLXtMeshMap;
                                   const Value     : PSingle    ) : LxResult;
    function ClearMapValue        (      Map       : PLXtMeshMap) : LxResult;
    function PolygonCount         (      Count     : PUInt32    ) : LxResult;
    function PolygonByIndex       (      Index     : UInt32     ;
                                         PolygonID : PLXtPolygon) : LxResult;
    function RepresentativePolygon(      PolygonID : PLXtPolygon;
                                         Index     : UInt32     ) : LxResult;
    function SharedPolygon        (      EdgeID    : PLXtEdge   ;
                                         PolygonID : PLXtPolygon) : LxResult;
    function IsBorder                                             : LxResult;
  end;

  ILxMeshMap  = interface
  [LXu_MESHMAP]
    function Spawn                 (  out VObj                   ) : LxResult   ;
    function Enumerate             (      Mode      : LXtMarkMode;
                                          Visitor   ,
                                          Monitor   : IUnknown   ) : LxResult   ;
    function Select                (      Map       : PLXtMeshMap) : LxResult   ;
    function SelectByName          (      &Type     : LXtID4     ;
                                    const Name      : PChar      ) : LxResult   ;
    function FilterByType          (      &Type     : LXtID4     ) : LxResult   ;
    function ID                                                    : PLXtMeshMap;
    function Name                  (const Name      : PChar      ) : LxResult   ;
    function &Type                 (      &Type     : LXtID4     ) : LxResult   ;
    function Dimension             (      Dimension : PUInt32    ) : LxResult   ;
    function IsEdgeMap                                             : LxResult   ;
    function IsContinuous                                          : LxResult   ;
    function ZeroDefault                                           : LxResult   ;
    function New                   (      Type_     : LXtID4     ;
                                    const Name_     : PChar      ;
                                          MapID     : PLXtMeshMap) : LxResult   ;
    function Remove                                                : LxResult   ;
    function Clear                                                 : LxResult   ;
    function EnumerateContinuous   (      Visitor   ,
                                          Point     : IUnknown   ) : LxResult   ;
    function EnumerateDiscontinuous(      Visitor   ,
                                          Point     ,
                                          Poly      : IUnknown   ) : LxResult   ;
    function EnumerateEdges        (      Visitor   ,
                                          Edge      : IUnknown   ) : LxResult   ;
  end;

  ILxMeshListener = interface
  [LXu_MESHLISTENER]
    procedure Destroy;
  end;

  ILxMeshFilter = interface
  [LXu_MESHFILTER]
    function &Type                         : UInt32  ;
    function Evaluate(    Mesh : IUnknown) : LxResult;
    function Generate(out VMesh          ) : LxResult;
  end;

  ILxMeshFilterBBox = interface
  [LXu_MESHFILTERBBOX]
    function Evaluate(Box : PLXtBBox) : LxResult;
  end;

function LXiPTYP_FACE       : LXtID4;
function LXiPTYP_CURVE      : LXtID4;
function LXiPTYP_BEZIER     : LXtID4;
function LXiPTYP_SUBD       : LXtID4;
function LXiPTYP_SPCH       : LXtID4;
function LXiPTYP_TEXT       : LXtID4;
function LXiPTYP_PSUB       : LXtID4;

function LXi_PTAG_MATR      : LXtID4;
function LXi_PTAG_PART      : LXtID4;
function LXi_PTAG_PICK      : LXtID4;
function LXi_PTAG_FONT      : LXtID4;
function LXi_PTAG_TEXT      : LXtID4;
function LXi_PTAG_JUST      : LXtID4;

function LXi_VMAP_OBJECTPOS : LXtID4;
function LXi_VMAP_MORPH     : LXtID4;
function LXi_VMAP_SPOT      : LXtID4;
function LXi_VMAP_NORMAL    : LXtID4;
function LXi_VMAP_TEXTUREUV : LXtID4;
function LXi_VMAP_WEIGHT    : LXtID4;
function LXi_VMAP_PICK      : LXtID4;
function LXi_VMAP_EPCK      : LXtID4;
function LXi_VMAP_RGB       : LXtID4;
function LXi_VMAP_RGBA      : LXtID4;
function LXi_VMAP_SUBDIV    : LXtID4;

implementation

function LXiPTYP_FACE       : LXtID4; inline;
begin
  Result := LXxID4('F','A','C','E');
end;
function LXiPTYP_CURVE      : LXtID4; inline;
begin
  Result := LXxID4('C','U','R','V');
end;
function LXiPTYP_BEZIER     : LXtID4; inline;
begin
  Result := LXxID4('B','E','Z','R');
end;
function LXiPTYP_SUBD       : LXtID4; inline;
begin
  Result := LXxID4('S','U','B','D');
end;
function LXiPTYP_SPCH       : LXtID4; inline;
begin
  Result := LXxID4('S','P','C','H');
end;
function LXiPTYP_TEXT       : LXtID4; inline;
begin
  Result := LXxID4('T','E','X','T');
end;
function LXiPTYP_PSUB       : LXtID4; inline;
begin
  Result := LXxID4('P','S','U','B');
end;

function LXi_PTAG_MATR      : LXtID4; inline;
begin
  Result := LXxID4('M','A','T','R');
end;
function LXi_PTAG_PART      : LXtID4; inline;
begin
  Result := LXxID4('P','A','R','T');
end;
function LXi_PTAG_PICK      : LXtID4; inline;
begin
  Result := LXxID4('P','I','C','K');
end;
function LXi_PTAG_FONT      : LXtID4; inline;
begin
  Result := LXxID4('F','O','N','T');
end;
function LXi_PTAG_TEXT      : LXtID4; inline;
begin
  Result := LXxID4('T','E','X','T');
end;
function LXi_PTAG_JUST      : LXtID4; inline;
begin
  Result := LXxID4('J','U','S','T');
end;

function LXi_VMAP_OBJECTPOS : LXtID4; inline;
begin
  Result := LXxID4('O','P','O','S');
end;
function LXi_VMAP_MORPH     : LXtID4; inline;
begin
  Result := LXxID4('M','O','R','F');
end;
function LXi_VMAP_SPOT      : LXtID4; inline;
begin
  Result := LXxID4('S','P','O','T');
end;
function LXi_VMAP_NORMAL    : LXtID4; inline;
begin
  Result := LXxID4('N','O','R','M');
end;
function LXi_VMAP_TEXTUREUV : LXtID4; inline;
begin
  Result := LXxID4('T','X','U','V');
end;
function LXi_VMAP_WEIGHT    : LXtID4; inline;
begin
  Result := LXxID4('W','G','H','T');
end;
function LXi_VMAP_PICK      : LXtID4; inline;
begin
  Result := LXxID4('P','I','C','K');
end;
function LXi_VMAP_EPCK      : LXtID4; inline;
begin
  Result := LXxID4('E','P','C','K');
end;
function LXi_VMAP_RGB       : LXtID4; inline;
begin
  Result := LXxID4('R','G','B',' ');
end;
function LXi_VMAP_RGBA      : LXtID4; inline;
begin
  Result := LXxID4('R','G','B','A');
end;
function LXi_VMAP_SUBDIV    : LXtID4; inline;
begin
  Result := LXxID4('S','U','B','V');
end;

end.

